﻿using Bnbjoy.Business.Abstract;
using Bnbjoy.Business.Common;
using Bnbjoy.Business.Concrete;
using Bnbjoy.Business.Constants;
using Bnbjoy.Business.Model.Dashboard;
using Bnbjoy.Domain.Abstract;
using Bnbjoy.Domain.Concrete;
using Bnbjoy.Domain.Entities;
using BnbjoyBackend.Api.Security;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;

namespace BnbjoyBackend.Api.Controllers
{
    public class OrderController : ApiController
    {
        [Route("api/order/new_dash_order")]
        [HttpPost]
        [Authorize(Roles = "BA,BE")]
        public async Task<HttpPostResponse> NewDashOrder([FromBody]NewOrderModel model)
        {
            if (!ModelState.IsValid)
            {
                var message = string.Join(" | ", ModelState.Values
                              .SelectMany(v => v.Errors)
                              .Select(e => e.ErrorMessage));
                return new HttpPostResponse(HttpStatusCode.BadRequest, message);
            }

            //最多支持不超过两个月的预订
            if (model.ToDate > DateTime.Now.AddMonths(2).AddDays(1))
            {
                return new HttpPostResponse(HttpStatusCode.BadRequest, "时间范围错误");
            }

            using (IOrderService orderService = new OrderService(new OrderRepository()))
            {
                try
                {
                    //得到order type和order id
                    int orderType = CommonUtil.ObtainValueFromEnumStr(typeof(OrderType), model.OrderType);
                    var orderId = BusinessUtil.GenOrderId((OrderType)orderType);

                    //得到订单来源
                    int channel = CommonUtil.ObtainValueFromEnumStr(typeof(ChannelType), model.Channel);
                    //得到订单支付方式
                    int paymentType = CommonUtil.ObtainValueFromEnumStr(typeof(Bnbjoy.Business.Constants.PaymentType), model.PaymentType);

                    //获取手机号归属地
                    var mobileArea = await orderService.FetchMobileArea(model.ReserverMobile);

                    //新建订单
                    var order = new Order
                    {
                        OrderId = orderId,
                        Channel = channel,
                        PaymentType = paymentType,
                        OrderStatus = (int)OrderStatus.Confirmation, //通过dashboard创建订单，默认是已确认 
                        FromDate = model.FromDate,
                        ToDate = model.ToDate,
                        ArrivalTime = model.ArrivalTime, //到达时间，HH:mm
                        RoomStatus = (int)RoomStatus.Booked, //房间状态在订单创建完，改为已预订
                        ReserverUser = model.ReserverUser,
                        ReserverMobile = model.ReserverMobile,
                        MobileArea = mobileArea, //预订人手机归属地
                        BnbId = model.BnbId,
                        RoomTypeId = model.RoomTypeId,
                        RoomId = model.RoomId,
                        RoomNumber = model.RoomNumber,
                        RoomNights = model.RoomNights,
                        Amount = model.Amount,
                        OrderNotes = model.OrderNotes == null ? "" : model.OrderNotes.Trim(),
                        CreatedTime = DateTime.Now,
                        ModifyTime = DateTime.Now
                    };

                    List<Customer> customers = new List<Customer>();
                    foreach (var c in model.Customers)
                    {
                        var customer = new Customer
                        {
                            OrderId = order.OrderId,
                            CustomerId = Guid.NewGuid().ToString("n"),
                            CustomerName = c.CustomerName,
                            CustomerIdType = CommonUtil.ObtainValueFromEnumStr(typeof(Bnbjoy.Business.Constants.CustomerIdType), c.CustomerIdType),
                            CustomerIdNumber = c.CustomerIdNumber
                        };

                        customers.Add(customer);
                    }

                    List<OrderSpending> spendings = new List<OrderSpending>();
                    foreach (var s in model.Spendings)
                    {
                        var spending = new OrderSpending
                        {
                            OrderId = order.OrderId,
                            SpendId = Guid.NewGuid().ToString("n"),
                            SpendType = CommonUtil.ObtainValueFromEnumStr(typeof(Bnbjoy.Business.Constants.SpenItemType), s.SpendType),
                            Amount = s.Amount,
                            Notes = s.Notes == null ? "" : s.Notes.Trim()
                        };

                        spendings.Add(spending);
                    }

                    OrderResponse result = await orderService.NewOrder((OrderType)orderType, order, customers, spendings);
                    if (result != null)
                    {
                        string resultJson = JsonHelper.ConvertObjectToJson(result);
                        return new HttpPostResponse(HttpStatusCode.OK, resultJson);
                    }
                    else
                    {
                        return new HttpPostResponse(HttpStatusCode.Forbidden, "订单号重复");
                    }
                }
                catch (Exception ex)
                {
                    return new HttpPostResponse(HttpStatusCode.InternalServerError, ex.Message);
                }
            }
        }

        [Route("api/order/fetch_available_rooms")]
        [HttpPost]
        [Authorize(Roles = "BA,BE")]
        public async Task<HttpPostResponse> FetchAvailableRooms([FromBody]QueryAvailableRoomsParam param)
        {
            if (!ModelState.IsValid)
            {
                var message = string.Join(" | ", ModelState.Values
                              .SelectMany(v => v.Errors)
                              .Select(e => e.ErrorMessage));
                return new HttpPostResponse(HttpStatusCode.BadRequest, message);
            }

            try
            {
                using (IOrderService orderService = new OrderService(new OrderRepository()))
                {
                    var result = await orderService.FetchAvailableRooms(param);
                    if (result != null)
                    {
                        string resultJsonStr = JsonHelper.ConvertObjectToJson(result);
                        return new HttpPostResponse(HttpStatusCode.OK, resultJsonStr);
                    }
                    else
                    {
                        return new HttpPostResponse(HttpStatusCode.Forbidden, "获取数据失败");
                    }
                }
            }
            catch (Exception ex)
            {
                return new HttpPostResponse(HttpStatusCode.InternalServerError, ex.Message);
            }
        }

        [Route("api/order/fetch_basic_rooms_info")]
        [HttpPost]
        [Authorize(Roles = "BA,BE")]
        public async Task<HttpPostResponse> FetchAvailableRooms([FromBody]QueryRoomsBasiceInfoParam param)
        {
            if (!ModelState.IsValid)
            {
                var message = string.Join(" | ", ModelState.Values
                              .SelectMany(v => v.Errors)
                              .Select(e => e.ErrorMessage));
                return new HttpPostResponse(HttpStatusCode.BadRequest, message);
            }

            try
            {
                using (IRoomTypeService roomTypeService = new RoomTypeService(new RoomTypeRepository()))
                {
                    var result = await roomTypeService.FetchAllBasicRoomsInfo(param.FromDate, param.ToDate, param.BnbId);
                    if (result != null)
                    {
                        string resultJsonStr = JsonHelper.ConvertObjectToJson(result);
                        return new HttpPostResponse(HttpStatusCode.OK, resultJsonStr);
                    }
                    else
                    {
                        return new HttpPostResponse(HttpStatusCode.Forbidden, "获取数据失败");
                    }
                }
            }
            catch (Exception ex)
            {
                return new HttpPostResponse(HttpStatusCode.InternalServerError, ex.Message);
            }
        }
    }
}
